package com.edoomath.api.web.controller.trade;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.utils.JsonUtils;
import com.edoomath.api.entity.Recharge;
import com.edoomath.api.handler.SmsSender;
import com.edoomath.api.servcice.PaymentCallbackService;
import com.edoomath.api.servcice.PaymentRequestService;
import com.edoomath.api.servcice.RechargeOrderService;
import com.edoomath.api.servcice.UserService;
import com.edoomath.entity.recharge.RechargeOrder;
import com.edoomath.entity.trade.PaymentRequest;
import com.edoomath.entity.user.User;

/**
 * 
 * @author mohanlan
 *
 */
@RestController
@RequestMapping("/recharge")
public class RechargeCenterController {

	private static final Logger logger = LoggerFactory.getLogger(RechargeCenterController.class);

	@Autowired
	private UserService userService;

	@Autowired
	private SmsSender smsSender;

	@Autowired
	private RechargeOrderService rechargeOrderService;
	
	@Autowired
	private PaymentRequestService paymentRequestService;
	
	@Autowired
	private PaymentCallbackService paymentCallbackService;

	/**
	 * 
	 * @param user
	 * @param shopping
	 * @param code
	 * @param token
	 * @param currentUrl
	 * @return
	 */
	@RequestMapping(value = "/orders", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public HttpResult onSumitOrder(@RequestBody Recharge recharge,
								   @RequestParam(name = "code", required = false) String code,
								   @RequestParam(name = "token", required = false) String token,
								   @RequestParam(name = "unionid", required = false) String unionid) {

		HttpResult httpResult = new HttpResult();

		try {
			
			logger.info("get rechare [{}]", JsonUtils.toJson(recharge));
			
			User user = userService.load(unionid);

			if (user == null) {
				httpResult.fail("500").message("用户数据异常");
				return httpResult;
			}

			if (StringUtils.isBlank(user.getMobile()) && (StringUtils.isBlank(recharge.getMobile())
					|| StringUtils.isBlank(token) || StringUtils.isBlank(code))) {
				httpResult.fail("500").message("请先绑定手机号");
				return httpResult;
			}

			if (StringUtils.isNotBlank(recharge.getMobile()) && StringUtils.isNotBlank(token)
					&& StringUtils.isNotBlank(code)) {

				boolean valid = smsSender.checkVerifyCode(recharge.getMobile(), code, token);
				if (!valid) {
					httpResult.fail("500").message("验证码错误");
				}
			}
			
			RechargeOrder rechargeOrder = rechargeOrderService.createOrder(recharge, user);


			httpResult.success().data("order", rechargeOrder.getId()).message("创建订单成功");

		} catch (Exception e) {
			httpResult.fail("500").message("创建订单失败");
			logger.error("#onSumitOrder() - occur exception=[{}]", e);
		}

		return httpResult;
	}

	/**
	 * 
	 * @param orderId
	 * @param unionid
	 * @param currentUrl
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/pay", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public HttpResult onPay(@RequestParam("orderId") Long orderId,
							@RequestParam("unionid") String unionid,
							HttpServletRequest request) {

		HttpResult httpResult = new HttpResult();

		try {
			
			User user = userService.load(unionid);
			
			RechargeOrder rechargeOrder = rechargeOrderService.load(orderId);
			
			String xRealIpHeader = request.getHeader("X-Real-IP"); // Only available after NGINX redirect
			String remoteIp = StringUtils.isBlank(xRealIpHeader) ? request.getRemoteAddr() : xRealIpHeader;
			logger.trace("#join() - Get remote IP address [{}].", remoteIp);
			
			Map<String, Object> payConfig = rechargeOrderService.prepay(rechargeOrder, user, remoteIp);
			return httpResult.success().data("payConfig", payConfig);

		} catch (Exception e) {
			logger.error("#prepay - occurs error", e);
			throw BusinessException.newInstance("500", "充值失败");
		}
	}
	
	/**
	 * 
	 * @param body
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/callback", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public @ResponseBody HttpResult onPaid(@RequestBody String body,
										   HttpServletRequest request) {
		
		Map<String, Object> params = JsonUtils.parse(body);
        
        logger.trace("#onPaid - Get rquest number [{}], order number [{}], amount [{}], pay time [{}], channel [{}].", 
                      params.get("requestNo"), params.get("orderNo"), params.get("transactionCode"), params.get("amount"), params.get("paymentTime"));
        
        HttpResult httpResult = new HttpResult();
        
        try {
        	
        	String requestCode = params.get("requestNo").toString();
            
            PaymentRequest paymentRequest = paymentRequestService.load(requestCode);
            
            // validate payment request
            if(paymentRequest == null) {
                throw new BusinessException("支付回调数据错误");
            }
            
            // validate payment request & order code
            String orderCode = params.get("orderNo").toString();
            if(!StringUtils.equalsIgnoreCase(orderCode, paymentRequest.getOrderCode())) {
                throw new BusinessException("支付回调数据异常");
            }
            
            // do pay order
            String payCode = params.get("transactionCode").toString();
            String payTime = params.get("paymentTime").toString();
            int amount = Integer.parseInt(params.get("amount").toString());
            
            RechargeOrder rechargeOrder = paymentCallbackService.pay(paymentRequest, orderCode, payCode, payTime, amount);
            
            smsSender.sendMessage("17621360181", "【陆老师小课堂】有新的用户[" + rechargeOrder.getUser().getNickname() + "]充值课时。充值订单号为["+rechargeOrder.getCode()+"]。充值金额为["+rechargeOrder.getPaidPrice()+"]");
            
            httpResult.success().message("支付回调成功");
            
            // check order & update order, product things
            logger.trace("#onPaid() - Synchronizing order with result [{}] !!!!!!!!", httpResult.getMessage());
        	
        } catch (BusinessException e) {
            httpResult.fail("500").message(e.getMessage());
        } catch (Exception e) {
            logger.error("#prepare - occurs error", e);
            httpResult.fail("500").message("请求支付数据失败");
        }
        
        return httpResult;
		
	}
}
